package com.own.component.log.operation.util;

import com.alibaba.fastjson2.JSON;
import com.own.component.log.operation.aop.LogOperationAop;
import com.own.component.log.operation.aop.LogOperationModuleAop;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.List;

/**
 * LogOperationUtil
 *
 * @author chenxueli
 * @date 2023-08-26 10:21:00
 */
public class LogOperationUtil {

    /**
     * 获取模块名称
     *
     * @param point 切点
     * @param data  注解
     * @return 模块名称
     */
    public static String getModuleName(JoinPoint point, LogOperationAop data) {
        if (StringUtils.isNotBlank(data.moduleName())) {
            return data.moduleName();
        }
        // 类上的LogOperationModuleAop注解
        return getModuleName(point.getTarget().getClass(), data);
    }

    /**
     * 获取模块名称
     *
     * @param clazz 类
     * @param data  注解
     * @return 模块名称
     */
    public static String getModuleName(Class<?> clazz, LogOperationAop data) {
        // 类上的LogOperationModuleAop注解
        var logOperationModuleAop = clazz.getAnnotation(LogOperationModuleAop.class);
        if (logOperationModuleAop != null && StringUtils.isNotBlank(logOperationModuleAop.value())) {
            return logOperationModuleAop.value();
        }
        // 类上的Api注解
        var api = clazz.getAnnotation(Tag.class);
        if (api != null && StringUtils.isNotBlank(api.name())) {
            return api.name();
        }
        return "";
    }

    /**
     * 获取操作名称
     *
     * @param point 切点
     * @param data  注解
     * @return 操作名称
     */
    public static String getOperationName(JoinPoint point, LogOperationAop data) {
        if (StringUtils.isNotBlank(data.operationName())) {
            return data.operationName();
        }
        // 获取方法上的ApiOperation注解
        var signature = (MethodSignature) point.getSignature();
        return getOperationName(signature.getMethod(), data);
    }

    /**
     * 获取操作名称
     *
     * @param method 方法
     * @param data   注解
     * @return 操作名称
     */
    public static String getOperationName(Method method, LogOperationAop data) {
        var apiOperation = method.getAnnotation(Operation.class);
        if (apiOperation != null) {
            return apiOperation.summary();
        }
        return "";
    }

    /**
     * 解析对象
     *
     * @param object 对象
     * @return 解析后的字符串
     */
    public static String resolveObject(Object object) {
        if (object == null) {
            return "";
        }
        if (object instanceof Serializable) {
            return switch (object) {
                case List<?> list -> resolveList(list);
                case MultipartFile multipartFile -> multipartFile.getOriginalFilename();
                case File file -> file.getName();
                default -> JSON.toJSONString(object);
            };
        }
        return object.toString();
    }

    /**
     * 解析List
     *
     * @param list List
     * @return 解析后的字符串
     */
    public static String resolveList(List<?> list) {
        var resultList = list.stream().map(item -> item != null ? resolveObject(item) : null).toList();
        return JSON.toJSONString(resultList);
    }

}
